﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using TTGame;

/*
 * BuffManager
 *
 *
 *
 * 依赖：
 *
 * ！不写重复代码！
 * @author TTun
 * @date 8/29/2017 4:25:38 PM
 */
namespace TTGameEngine {

public class BuffManager : MonoBehaviour {

    static BuffManager m_instance;
    static public bool BuffLogFlag = true;

    //buff总数据表，使用时才会实例成Buff
    Dictionary<int, BaseBuffData> m_buffdatas = new Dictionary<int, BaseBuffData>();

    public static BuffManager Share() {
        if(m_instance == null) {
            GameObject obj = new GameObject("BuffManager");
            m_instance = obj.AddComponent<BuffManager>();
        }
        return m_instance;
    }

    // Use this for initialization
    void Awake() {
    }

    // Update is called once per frame
    void Update() {

    }

    public Buff ObtainBuff(int id) {
        BaseBuffData buffData = GetBuffData(id);
        Buff buff = null;
        if(buffData != null) {
            buff = CreateBuffWithData(buffData);
        }
        return buff;
    }

    public BaseBuffData GetBuffData(int id) {
        BaseBuffData buffData = null;
        m_buffdatas.TryGetValue(id, out buffData);
        return buffData;
    }

    Buff createTypeBuff<T1, T2>(BaseBuffData buffData) where T1: Buff, new() where T2: BaseBuffData {
        T1 typeBuff = new T1();
        T2 typeBuffData = buffData as T2;
        if(typeBuffData == null) {
            BuffLogError("BuffData类型不对，无法转换成[{0}]", buffData.m_buffType.ToString());
        }
        typeBuff.Init(typeBuffData);
        return typeBuff;
    }

//     BaseBuffData CreateBuffDataWithServerData(BattleServerData.BuffSData buffSData) {
//         BaseBuffData buffdata = null;
//         BuffType type = (BuffType)buffSData.type;
//         switch(type) {
//             case BuffType.PropBuff: {
//                     PropBuffData typeBuffdata = new PropBuffData();
//                     buffdata = typeBuffdata;
//                     PropChange propChange = new PropChange();
//                     propChange.propID = buffSData.gain.intValue();
//                     propChange.valueChange = buffSData.par_1;
//                     propChange.precentChange = buffSData.par_2 / 100f;
//                     typeBuffdata.m_propsChange.Add(propChange);
//                 }
//                 break;
//             case BuffType.HPBuff: {
//                     HPBuffData typeBuffdata = new HPBuffData();
//                     buffdata = typeBuffdata;
//                     if(buffSData.gain == "immediately") {
//                         typeBuffdata.m_hpChange.valueChange = buffSData.par_1;
//                         typeBuffdata.m_hpChange.precentChange = buffSData.par_2 / 100f;
//                     } else if(buffSData.gain == "hot") {
//                         typeBuffdata.m_hpChangeDot.valueChange = buffSData.par_1;
//                         typeBuffdata.m_hpChangeDot.precentChange = buffSData.par_2 / 100f;
//                         typeBuffdata.m_hpChangeDot.changeCount = buffSData.par_3;
//                     }
//                 }
//                 break;
//             case BuffType.ShieldBuff: {
//                     ShieldBuffData typeBuffdata = new ShieldBuffData();
//                     buffdata = typeBuffdata;
//                     typeBuffdata.valueChange = buffSData.par_1;
//                     typeBuffdata.precentChange = buffSData.par_2 / 100f;
//                     typeBuffdata.shieldInitLayer = buffSData.par_3;
//                     typeBuffdata.isOverHurt = false;
//                 }
//                 break;
//             case BuffType.ReceiveDamageBuff: {
//                     ReciveDamageBuffData typeBuffdata = new ReciveDamageBuffData();
//                     buffdata = typeBuffdata;
//                     typeBuffdata.m_dmgChange.valueChange = buffSData.par_1;
//                     typeBuffdata.m_dmgChange.precentChange = buffSData.par_2 / 100f;
//                 }
//                 break;
//             case BuffType.AttackDamageBuff: {
//                     AttackDamageBuffData typeBuffdata = new AttackDamageBuffData();
//                     buffdata = typeBuffdata;
//                     typeBuffdata.m_dmgChange.valueChange = buffSData.par_1;
//                     typeBuffdata.m_dmgChange.precentChange = buffSData.par_2 / 100f;
//                 }
//                 break;
//             case BuffType.StateBuff: {
//                     StateBuffData typeBuffdata = new StateBuffData();
//                     buffdata = typeBuffdata;
//                     if(buffSData.gain == "stun") {
//                         typeBuffdata.m_controlState = ControlState.Stun;
//                     }
//                 }
//                 break;
//         }
//
//         buffdata.BuffID = buffSData.id;
//         buffdata.effectPrefab = buffSData.effect;
//         buffdata.effectPos = buffSData.effectPos;
//         buffdata.m_duration = buffSData.last;
//         buffdata.m_maxOverlayLayer = buffSData.update;
//         buffdata.OverLayType = buffSData.OverLayType;
//         buffdata.OverLayPriority = buffSData.OverLayPriority;
//
//
//         return buffdata;
//     }

    Buff CreateBuffWithData(BaseBuffData buffData) {
        BuffType buffType = buffData.m_buffType;
        Buff buff = null;
        switch(buffType) {
            case BuffType.PropBuff: {
                    buff = createTypeBuff<PropBuff, PropBuffData>(buffData);
                }
                break;
            case BuffType.HPBuff: {
                    buff = createTypeBuff<HPBuff, HPBuffData>(buffData);
                }
                break;
            case BuffType.ShieldBuff: {
                    buff = createTypeBuff<ShieldBuff, ShieldBuffData>(buffData);
                }
                break;
            case BuffType.ReceiveDamageBuff: {
                    buff = createTypeBuff<DamagePreventBuff, ReciveDamageBuffData>(buffData);
                }
                break;
            case BuffType.AttackDamageBuff: {
                    buff = createTypeBuff<DamageIncBuff, AttackDamageBuffData>(buffData);
                }
                break;
            case BuffType.StateBuff: {
                    buff = createTypeBuff<StateBuff, StateBuffData>(buffData);
                }
                break;
        }
        return buff;
    }

    /// <summary>
    /// 从服务器读取BuffData
    /// </summary>
    public void LoadFromServerData() {
// #if UNITY_EDITOR
//         if(DebugSetting.Self.Debug_LocalScene) {
//             Debug_loadLocalBuffDatas();
//         } else
// #endif
//         {
//             List<BattleServerData.BuffSData> buffSDatas = BattleServerData.Share().buffSDatas;
//             for(int i = 0; i < buffSDatas.Count; i++) {
//                 var buffdata = buffSDatas[i];
//                 BaseBuffData buffBaseData = CreateBuffDataWithServerData(buffdata);
//                 m_buffdatas.TryAdd(buffBaseData.BuffID, buffBaseData);
//             }
// #if UNITY_EDITOR
//             if(DebugSetting.Self.Debug_LocalScene == false) {
//                 LocalBuffDatas localBuffData = gameObject.AddComponentSafe<LocalBuffDatas>();
//                 localBuffData.Desc = "服务器下发的数据";
//                 localBuffData.ShowBuffDatas(m_buffdatas);
//             }
// #endif
//         }
    }

    public void Debug_loadLocalBuffDatas() {
        var hpBuffData = LocalBuffDatas.Self.m_hpBuffdatas;
        for(int i = 0; i < hpBuffData.Count; i++) {
            hpBuffData[i].m_buffType = BuffType.HPBuff;
            m_buffdatas.Add(hpBuffData[i].BuffID, hpBuffData[i]);
        }
        var propBuffData = LocalBuffDatas.Self.m_propBuffdatas;
        for(int i = 0; i < propBuffData.Count; i++) {
            propBuffData[i].m_buffType = BuffType.PropBuff;
            m_buffdatas.Add(propBuffData[i].BuffID, propBuffData[i]);
        }
        var shieldBuffData = LocalBuffDatas.Self.m_shieldBuffdatas;
        for(int i = 0; i < shieldBuffData.Count; i++) {
            shieldBuffData[i].m_buffType = BuffType.ShieldBuff;
            m_buffdatas.Add(shieldBuffData[i].BuffID, shieldBuffData[i]);
        }
        var damageIncBuffData = LocalBuffDatas.Self.m_attackDamageBuffDatas;
        for(int i = 0; i < damageIncBuffData.Count; i++) {
            damageIncBuffData[i].m_buffType = BuffType.AttackDamageBuff;
            m_buffdatas.Add(damageIncBuffData[i].BuffID, damageIncBuffData[i]);
        }
        var damagePreventBuffData = LocalBuffDatas.Self.m_receiveDamageBuffDatas;
        for(int i = 0; i < damagePreventBuffData.Count; i++) {
            damagePreventBuffData[i].m_buffType = BuffType.ReceiveDamageBuff;
            m_buffdatas.Add(damagePreventBuffData[i].BuffID, damagePreventBuffData[i]);
        }
        var stateBuffData = LocalBuffDatas.Self.m_StateBuffDatas;
        for(int i = 0; i < stateBuffData.Count; i++) {
            stateBuffData[i].m_buffType = BuffType.StateBuff;
            m_buffdatas.Add(stateBuffData[i].BuffID, stateBuffData[i]);
        }
    }


    #region LOG方法
    public void BuffLog(string msgformat, params object[] args) {
        if(BuffLogFlag == false) {
            return;
        }
        DebugUtil.LogFormat("[Buff][{0}]",
                            string.Format(msgformat, args));
    }
    public void BuffLogWarning(string msgformat, params object[] args) {
        if(BuffLogFlag == false) {
            return;
        }
        DebugUtil.LogWarningFormat("[Buff][{0}]",
                                   string.Format(msgformat, args));
    }
    public void BuffLogError(string msgformat, params object[] args) {
        DebugUtil.LogErrorFormat("[Buff][{0}]",
                                 string.Format(msgformat, args));
    }
    #endregion


}

}
